
# gpt_sovits_tts.py
from pathlib import Path
import uuid
import requests
from config import app_config
from .tts_base import BaseTTS
from .tts_registry import register_tts
from config import app_config

@register_tts("gpt_sovits")
class GptSovitsTTS(BaseTTS):
    def __init__(self,gpt_model_path: str = None,sovits_model_path: str= None) -> None: # type: ignore
        self.gpt_model_path = gpt_model_path
        self.sovits_model_path = sovits_model_path
        # 设置模型路径
        call_set_gpt_model(self.gpt_model_path)
        call_set_sovits_model(self.sovits_model_path)
        print("初始化gpt_sovits的模型")


    def synthesize(self, text: str, **kwargs) -> str:
        # 支持运行时参数覆盖
        lang = kwargs.get("lang", "zh")
        prompt_lang = kwargs.get("prompt_lang", app_config.GPT_SOVITS_REFERENCE_AUDIO_LANG)
        ref_audio_path = kwargs.get("ref_audio_path", app_config.GPT_SOVITS_REFERENCE_AUDIO_PATH)
        prompt_text = kwargs.get("prompt_text", app_config.GPT_SOVITS_REFERENCE_AUDIO_TEXT)

        # 生成唯一的输出文件名
        output_dir = app_config.TTS_FILE_OUT_PATH
        output_filename = f"tts_output_{uuid.uuid4().hex[:8]}.mp3"
        output_path = Path(output_dir) / output_filename

        response = requests.post(
            f"{app_config.GPT_SOVITS_HOST}/tts",
            json={
                "text": text,
                "text_lang": lang,
                "ref_audio_path": ref_audio_path,
                "prompt_lang": prompt_lang,
                "prompt_text": prompt_text,
                "speed_factor": 1
            }
        )
        if response.status_code == 200:
            with open(output_path, "wb") as f:
                f.write(response.content)
            return str(output_path)
        else:
            raise Exception(f"GPT-Sovits TTS请求失败: {response.status_code}, {response.text}")

    def cleanup(self):
        """GptSovitsTTS 无需显式释放资源"""
        pass


def call_set_gpt_model(model_path: str):
    response = requests.get(
        f"{app_config.GPT_SOVITS_HOST}/set_gpt_weights",
        params={
            "weights_path": model_path or app_config.GPT_SOVITS_GPT_MODEL, # 如果传入的路径为空，则使用配置文件中的默认路径
        }
    )

    if response.status_code == 200:
        print(f"已切换到Sovits模型: {app_config.GPT_SOVITS_GPT_MODEL}")
    else:
        raise Exception(f"切换模型请求失败，状态码: {response.status_code}, 信息: {response.text}")
    
def call_set_sovits_model(model_path: str):
    response = requests.get(
        f"{app_config.GPT_SOVITS_HOST}/set_sovits_weights",
        params={
            "weights_path": model_path or app_config.GPT_SOVITS_SOVITS_MODEL, # 如果传入的路径为空，则使用配置文件中的默认路径
        }
    )

    if response.status_code == 200:
        print(f"已切换到Sovits模型: {app_config.GPT_SOVITS_SOVITS_MODEL}")
    else:
        raise Exception(f"切换模型请求失败，状态码: {response.status_code}, 信息: {response.text}")